/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
 *
 */

import * as fs from 'fs';
import { readFile } from 'fs/promises';
import os from 'os';
import * as path from 'path';

import { parseJsonText } from '../../common/util/parse-json/parse-json-util.js';
import { HvigorLogger } from '../log/hvigor-log.js';

export class Json5Reader {
  private static logger: HvigorLogger = HvigorLogger.getLogger(Json5Reader.name);

  /**
   * 获取json5对象
   *
   * @param {string} json5path json5路径
   * @param {any} encodingStr 编码方式
   */
  public static getJson5Obj(json5path: string, encodingStr = 'utf-8'): any {
    if (!fs.existsSync(json5path)) {
      Json5Reader.logger.printErrorExit('FILE_NOT_EXIST', [json5path]);
    }

    const text = fs.readFileSync(path.resolve(json5path), { encoding: encodingStr as BufferEncoding });

    try {
      return parseJsonText(text);
    } catch (e) {
      Json5Reader.handleException(json5path, e);
    }
  }

  /**
   * 异步API获取json5对象
   *
   * @param {string} json5path json5路径
   * @param {any} encodingStr 编码方式
   */
  public static async readJson5File(json5path: string, encodingStr = 'utf-8') {
    try {
      return readFile(json5path, { encoding: encodingStr as BufferEncoding }).then(parseJsonText);
    } catch (e) {
      Json5Reader.handleException(json5path, e);
    }
  }

  private static handleException(json5path: string, e: any) {
    if (e instanceof SyntaxError) {
      const msg = e.message.split('at ');
      if (msg.length === 2) {
        Json5Reader.logger.printErrorExit('JSON_READER_SYNTAX_ERROR', [msg[0].trim(), json5path, msg[1].trim()]);
      }
    }
    Json5Reader.logger.printErrorExit('NOT_CORRECT_JSON_FORMAT', [json5path]);
  }

  /**
   * 获取json5对象中某一个属性的值
   *
   * @param {any} json5对象 json5对象
   * @param {string} key json5对象中的属性名称，多个层级之间用.分隔
   */
  public static getJson5ObjProp(obj: any, key: string): any {
    const parts = key.split('.');
    let curr = obj;
    for (const part of parts) {
      if (curr[part] === undefined) {
        return undefined;
      }
      curr = curr[part];
    }
    return curr;
  }
}
